<template>
  <div class="table-box">
    <pro-table ref="proTableRef" row-key="id" :columns="columns" :request-api="getRolePageApi">
      <!-- 表格 header 按钮 -->
      <template #tableHeader>
        <el-button v-auth="'sys:role:add'" type="primary" :icon="CirclePlus" @click="handleAdd"> 新增角色 </el-button>
      </template>
      <!-- 状态 -->
      <template #isEnable="scope">
        <el-switch
          v-model="scope.row.isEnable"
          :loading="scope.row.loading"
          active-text="已启用"
          inactive-text="已禁用"
          inline-prompt
          :before-change="handleEnable.bind(scope, scope.row)"
        />
      </template>
      <!-- 角色操作 -->
      <template #operation="{ row }">
        <el-button v-auth="'sys:role:edit'" type="primary" link :icon="EditPen" @click="handleEdit(row)"> 编辑 </el-button>
        <el-button v-auth="'sys:role:allocation'" type="primary" link :icon="EditPen" @click="handleDistribution(row)">
          资源分配
        </el-button>
        <el-button v-auth="'sys:role:del'" type="danger" link :icon="Delete" @click="handleDelete(row)"> 删除 </el-button>
      </template>
    </pro-table>
    <!-- 编辑角色 -->
    <role-edit ref="editDialogRef" />
    <!-- 资源分配 -->
    <role-distribution-resource ref="distributionResourceDialogRef" />
  </div>
</template>

<script setup lang="ts">
import type { ProTableInstance, ColumnProps } from "@/components/ProTable/interface";
import type { SysRole } from "@/api/interface";
import { ref } from "vue";
import { useHandleData } from "@/hooks/useHandleData";
import { statusConst } from "@/utils/dict";
import {
  addRoleApi,
  editRoleApi,
  switchEnableRoleApi,
  deleteRoleApi,
  distributionResourceApi,
  getRoleMenusApi,
  getRoleResourceApi,
  getRolePageApi
} from "@/api/modules/system/role";
import ProTable from "@/components/ProTable/index.vue";
import RoleEdit from "./components/edit.vue";
import RoleDistributionResource from "./components/distributionResource.vue";

import Delete from "~icons/ep/delete";
import EditPen from "~icons/ep/edit-pen";
import CirclePlus from "~icons/ep/circle-plus";

defineOptions({
  name: "SystemRole"
});

/** 表格实例 */
const proTableRef = ref<ProTableInstance>();
/** 编辑弹窗实例 */
const editDialogRef = ref<InstanceType<typeof RoleEdit> | null>(null);
/** 资源分配弹窗实例 */
const distributionResourceDialogRef = ref<InstanceType<typeof RoleDistributionResource> | null>(null);

/** 表格配置项 */
const columns: ColumnProps[] = [
  { prop: "name", label: "角色名称", align: "left", width: 200, search: { el: "input" } },
  { prop: "code", label: "角色编码", align: "left", width: 200 },
  { prop: "remarks", label: "备注信息", align: "left" },
  { prop: "isEnable", label: "状态", width: 100, enum: statusConst, search: { el: "select" } },
  { prop: "operation", label: "操作", width: 240, fixed: "right" }
];

/**
 * 添加角色
 *
 * @returns void
 */
const handleAdd = () => {
  const editParams = {
    title: "添加角色",
    role: {
      menuIds: []
    },
    getTableList: proTableRef.value?.getTableList,
    submitApi: addRoleApi
  };
  editDialogRef.value?.acceptParams(editParams);
};

/**
 * 编辑角色
 *
 * @param param 选中的角色
 * @returns void
 */
const handleEdit = (param: Partial<SysRole.Result>) => {
  getRoleMenusApi({ id: param.id! })
    // 获取角色已分配的菜单信息
    .then(({ data }) => {
      const role = { ...param } as SysRole.Form;
      role.menuIds = data;
      return Promise.resolve(role);
    })
    // 打开编辑弹窗
    .then(role => {
      const editParams = {
        title: "编辑角色",
        role,
        getTableList: proTableRef.value?.getTableList,
        submitApi: editRoleApi
      };
      editDialogRef.value?.acceptParams(editParams);
    });
};

/**
 * 启用/禁用角色
 *
 * @param param 选中的角色
 * @returns void
 */
const handleEnable = (param: Partial<SysRole.Result> & { loading?: boolean }) => {
  param.loading = true;
  return switchEnableRoleApi({ id: param.id! })
    .then(({ data }) => {
      if (data) {
        return Promise.resolve(true);
      } else return Promise.reject(new Error("修改状态失败"));
    })
    .finally(() => {
      param.loading = false;
    });
};

/**
 * 删除角色
 *
 * @param param 选中的角色
 * @returns void
 */
const handleDelete = (param: Partial<SysRole.Result>) => {
  useHandleData(deleteRoleApi, { ids: [param.id] }, `删除【${param.name}】角色`).then(res => {
    if (res) proTableRef.value?.getTableList();
  });
};

/**
 * 资源分配
 *
 * @param param 选中的角色
 * @returns void
 */
const handleDistribution = (param: Partial<SysRole.Result>) => {
  getRoleResourceApi({ id: param.id! }).then(({ data }) => {
    const role = { ...param } as SysRole.ResourceForm;
    role.routes = data;
    const editParams = {
      title: "资源分配",
      role,
      submitApi: distributionResourceApi
    };
    distributionResourceDialogRef.value?.acceptParams(editParams);
  });
};
</script>
